<template>
  <Drawer v-model:visible="visible" position="right">
    <div class="theme-switcher">
      <div>
        <h4 style="margin-top: 0">外观</h4>
        <div>
          <select-button
            v-model="theme.dark"
            :options="[
              { label: '浅色', value: false },
              { label: '深色', value: true },
            ]"
            option-label="label"
            option-value="value"
            :allowEmpty="false"
          />
        </div>
      </div>

      <div>
        <h4>缩放</h4>
        <div class="theme-scale">
          <Button
            :disabled="theme.scale == 10"
            icon="pi pi-minus"
            text
            rounded
            @click="theme.scale -= 2"
          />
          <RadioButton v-model="theme.scale" :value="10" />
          <RadioButton v-model="theme.scale" :value="12" />
          <RadioButton v-model="theme.scale" :value="14" />
          <RadioButton v-model="theme.scale" :value="16" />
          <RadioButton v-model="theme.scale" :value="18" />
          <Button
            :disabled="theme.scale == 18"
            icon="pi pi-plus"
            text
            rounded
            @click="theme.scale += 2"
          />
        </div>
      </div>

      <div>
        <h4>主题风格</h4>
        <div>
          <select-button
            v-model="theme.name"
            :options="presetOptions"
            :allowEmpty="false"
          />
        </div>
      </div>

      <div>
        <div>
          <h4>主题色</h4>
          <div class="theme-colors">
            <template v-for="(colors, name) of primitive" :key="name">
              <div v-if="name != 'borderRadius'" v-tooltip.bottom="name">
                <Button
                  rounded
                  :style="{
                    backgroundColor: `${colors['500']}`,
                    boxShadow:
                      theme.color.name === name
                        ? '0 0 0 2px ' +
                          (theme.dark ? '#000' : '#fff') +
                          ', 0 0 0 4px ' +
                          colors['500'] +
                          ', 0 1px 2px 0 black'
                        : 'none',
                  }"
                  :icon="theme.color.name === name ? 'pi pi-check' : ''"
                  @click="theme.color = { name, colors }"
                />
              </div>
            </template>
          </div>
        </div>

        <div>
          <h4>按钮波纹</h4>
          <ToggleSwitch v-model="theme.ripple" />
        </div>
      </div>
    </div>
  </Drawer>
</template>

<script>
import { $t, updatePrimaryPalette } from '@primevue/themes'
import Aura from '@primevue/themes/aura'
import Lara from '@primevue/themes/lara'
import Nora from '@primevue/themes/nora'
import storage from '@/utils/storage'

export default {
  emits: ['update:modelValue'],
  props: {
    modelValue: {
      type: Boolean,
      default: false,
    },
  },
  data() {
    return {
      presets: {
        Aura,
        Lara,
        Nora,
      },
      primitive: Aura.primitive,
      presetOptions: ['Aura', 'Lara', 'Nora'],
      theme: {
        dark: false,
        scale: 14,
        name: 'Lara',
        color: {
          name: 'emerald',
          colors: Aura.primitive.emerald,
        },
        ripple: true,
      },
    }
  },
  computed: {
    visible: {
      get() {
        return this.modelValue
      },
      set(value) {
        this.$emit('update:modelValue', value)
      },
    },
  },
  watch: {
    'theme.dark'() {
      this.onDarkToggler()
      this.saveTheme()
    },
    'theme.scale'() {
      this.onScaleChange()
      this.saveTheme()
    },
    'theme.name'() {
      this.onPresetChange()
      this.saveTheme()
    },
    'theme.color'() {
      this.onColorChange()
      this.saveTheme()
    },
    'theme.ripple'() {
      this.onRippleToggler()
      this.saveTheme()
    },
  },
  mounted() {
    this.initTheme()
  },
  methods: {
    initTheme() {
      const theme = storage.get('theme')
      if (!theme) {
        return
      }

      this.theme.dark = theme.dark
      this.theme.scale = theme.scale
      this.theme.name = theme.name
      this.theme.color = theme.color
    },
    saveTheme() {
      storage.set('theme', this.theme)
    },

    onDarkToggler() {
      document.getElementsByTagName('html')[0].classList.toggle('p-dark')
    },

    onScaleChange() {
      document.getElementsByTagName('html')[0].style.fontSize =
        this.theme.scale + 'px'
    },

    onPresetChange() {
      const preset = this.presets[this.theme.name]
      $t().preset(preset).use({ useDefaultOptions: true })
      updatePrimaryPalette(this.theme.color.colors)
    },

    onColorChange() {
      updatePrimaryPalette(this.theme.color.colors)
    },

    onRippleToggler() {
      this.$primevue.config.ripple = this.theme.ripple
    },
  },
}
</script>
<style lang="scss">
.config-button {
  .pi-cog {
    font-size: 2rem;
  }
  box-shadow: -0.25rem 0 1rem #00000026;
}

.theme-switcher {
  padding: 1rem;

  h4 {
    margin: 1.5rem 0 1rem;
  }

  .theme-colors {
    display: flex;
    flex-wrap: wrap;

    div {
      flex: 0 0 25%;
      display: flex;
      justify-content: center;
      align-items: center;
      height: 4rem;

      button {
        width: var(--p-button-icon-only-width);
        height: var(--p-button-icon-only-width);
        border: none;
      }

      button:hover {
        border: none !important;
      }
    }
  }

  .theme-scale {
    display: flex;
    align-items: center;

    .p-radiobutton {
      margin: 0 0.2rem;
    }
  }
}
</style>
